from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

from utils import return_code
from utils.jwt_token import check_jwt_code


class CurrentUser:

    def __init__(self, user_id, username, exp):
        self.user_id = user_id
        self.username = username
        self.exp = exp


class MtbAuthenticationFailed(AuthenticationFailed):
    status_code = 200


class JwtTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        # 读取用户提交的jwt token

        # 方式一：在url中携带token，不方便
        # token = request.query_params.get('token')

        # 方式二：去请求头获取 Authorization: 401f7ac837da42b97f613d789819ff93537bee6a
        token = request.META.get('HTTP_AUTHORIZATION')
        if not token:
            # 状态码=200 {'code': 2000, 'error': '认证失败'}
            raise MtbAuthenticationFailed({'code': return_code.AUTH_FAILED, 'error': '认证失败'})
        # jwt token校验
        res = check_jwt_code(token)
        if res.get('error'):
            # 状态码=200 {'code': 2000, 'error': '...'}
            raise MtbAuthenticationFailed({'code': return_code.AUTH_FAILED, 'error': res.get('error')})

        # {'id': 1, 'username': 'yukefeng', 'exp': 1652651734}
        # 设置request.user: CurrentUser(**res)/request.auth: token
        return CurrentUser(**res), token


    def authenticate_header(self, request):
        return 'Bearer realm="API"'
